package com.ejie.general.cargador;

import com.ejie.general.comun.EstaticosClsTrazas;
import es.ejie.frmk.listeners.base.Q70ListenerUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public final class W83aCargadorEstaticos
  implements Serializable{//NOPMD
  private static final long serialVersionUID = 1L;
  private static final String COD_APLICACION = Q70ListenerUtils.getApplicationProperty("COD_APLICACION");
  private static final String FILE_PROPERTIES = "/html/datos/estaticos/" + COD_APLICACION.toLowerCase() + ".def.estaticos.properties";
  private static HashMap dependencias = null;
  private static String war;

  public static String referenciaEstaticos(String patron)
    throws IOException, Exception
  {
    return combinarDependencias(new String[] { patron });
  }

  public static String referenciaEstaticos(String[] patrones) throws IOException, Exception
  {
    return combinarDependencias(patrones);
  }
  
  public static String referenciaEstaticosJS(String[] patrones) throws IOException, Exception
  {
	  return combinarDependenciasJS(patrones);
  }
  public static String referenciaEstaticosCSS(String[] patrones) throws IOException, Exception
  {
	  return combinarDependenciasCSS(patrones);
  }

  public static String referenciaEstaticosUrlJS(String patrones, String cadena) throws IOException, Exception
  {
	  return combinarDependenciasUrl(new String[] { patrones }, cadena,true);
  }
  
  public static String referenciaEstaticosUrlJS(String[] patrones, String cadena) throws IOException, Exception
  {
	  return combinarDependenciasUrl(patrones, cadena,true);
  }
  
  public static String referenciaEstaticosUrlCSS(String patrones, String cadena) throws IOException, Exception
  {
	  return combinarDependenciasUrl(new String[] { patrones }, cadena,false);
  }
  
  public static String referenciaEstaticosUrlCSS(String[] patrones, String cadena) throws IOException, Exception
  {
	  return combinarDependenciasUrl(patrones, cadena,false);
  }

  private static String combinarDependencias(String[] listaBeans) {
    cargarDependencias();
    LinkedHashSet setDependenciasJs = new LinkedHashSet();
    LinkedHashSet setDependenciasCss = new LinkedHashSet();
    for (int i = 0; i < listaBeans.length; i++) {
      CargadorEstaticosBean bean = (CargadorEstaticosBean)dependencias.get(listaBeans[i]);
      if (bean != null) {
        for (int j = 0; j < bean.getJs().length; j++)
          setDependenciasJs.add(bean.getJs()[j]);
        for (int j = 0; j < bean.getCss().length; j++)
          setDependenciasCss.add(bean.getCss()[j]);
      }
    }
    return generarScript(setDependenciasJs, setDependenciasCss);
  }
  
  private static String combinarDependenciasJS(String[] listaBeans) {
	  cargarDependencias();
	  LinkedHashSet setDependenciasJs = new LinkedHashSet();
	  for (int i = 0; i < listaBeans.length; i++) {
		  CargadorEstaticosBean bean = (CargadorEstaticosBean)dependencias.get(listaBeans[i]);
		  if (bean != null) {
			  for (int j = 0; j < bean.getJs().length; j++)
				  setDependenciasJs.add(bean.getJs()[j]);
		  }
	  }
	  return generarScriptJS(setDependenciasJs);
  }
  
  private static String combinarDependenciasCSS(String[] listaBeans) {
	  cargarDependencias();
	  LinkedHashSet setDependenciasJs = new LinkedHashSet();
	  LinkedHashSet setDependenciasCss = new LinkedHashSet();
	  for (int i = 0; i < listaBeans.length; i++) {
		  CargadorEstaticosBean bean = (CargadorEstaticosBean)dependencias.get(listaBeans[i]);
		  if (bean != null) {
			  for (int j = 0; j < bean.getJs().length; j++)
				  setDependenciasJs.add(bean.getJs()[j]);
			  for (int j = 0; j < bean.getCss().length; j++)
				  setDependenciasCss.add(bean.getCss()[j]);
		  }
	  }
	  return generarScriptCSS(setDependenciasCss);
  }

  private static String combinarDependenciasUrl(String[] listaBeans, String cadena,boolean js) {//NOPMD
    cargarDependencias();
    LinkedHashSet setDependenciasJs = new LinkedHashSet();
    LinkedHashSet setDependenciasCss = new LinkedHashSet();
    for (int i = 0; i < listaBeans.length; i++) {
     CargadorEstaticosBean bean = (CargadorEstaticosBean)dependencias.get(listaBeans[i]);
      if (bean != null) {
        for (int j = 0; j < bean.getJs().length; j++)
          setDependenciasJs.add(bean.getJs()[j]);
        for (int j = 0; j < bean.getCss().length; j++)
          setDependenciasCss.add(bean.getCss()[j]);
      }
    }
    if(js){
    	return generarScriptUrlJS(setDependenciasJs, cadena);
    }else{
    	return generarScriptUrlCSS(setDependenciasCss, cadena);    	
    }
  }

  private static void cargarDependencias()
  {
    if (dependencias == null) {
      dependencias = new HashMap();

      InputStream input = W83aCargadorEstaticos.class.getResourceAsStream(FILE_PROPERTIES);

      BufferedReader reader = new BufferedReader(new InputStreamReader(input));
      StringBuffer sb = new StringBuffer();

      String line = null;
      try {
        while ((line = reader.readLine()) != null)
          sb.append(line + "\n");//NOPMD
      }
      catch (IOException e) {
        e.printStackTrace();
      } finally {
        try {
          input.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      try
      {
         JSONObject fichero = new JSONObject(sb.toString());
           JSONArray names = fichero.names();
           for (int i = 0; i < names.length(); i++) {
             CargadorEstaticosBean bean = new CargadorEstaticosBean();//NOPMD
             String nombre = names.get(i).toString();
             bean.setNombre(nombre);
             JSONObject obj = fichero.getJSONObject(nombre);
             bean.setJQueryVersion((String)obj.get("jqueryversion"));

             JSONArray arrayJS = obj.getJSONArray("js");
             RecursoEstaticosBean[] ss = new RecursoEstaticosBean[arrayJS.length()];//NOPMD
             for (int j = 0; j < arrayJS.length(); j++) {
               JSONObject dependencia = new JSONObject(arrayJS.get(j).toString());//NOPMD
               RecursoEstaticosBean recursoBean = new RecursoEstaticosBean();//NOPMD
               recursoBean.setName(dependencia.get("name").toString());
               if (dependencia.has("type"))
                 recursoBean.setType(dependencia.get("type").toString());
               ss[j] = recursoBean;
          }
             bean.setJs(ss);

             JSONArray arrayCSS = obj.getJSONArray("css");

             RecursoEstaticosBean[] ss2 = new RecursoEstaticosBean[arrayCSS.length()];//NOPMD
             for (int j = 0; j < arrayCSS.length(); j++) {
               JSONObject dependencia = new JSONObject(arrayCSS.get(j).toString());//NOPMD
               RecursoEstaticosBean recursoBean = new RecursoEstaticosBean();//NOPMD
               recursoBean.setName(dependencia.get("name").toString());
               if (dependencia.has("type"))
                 recursoBean.setType(dependencia.get("type").toString());
               ss2[j] = recursoBean;
          }

             bean.setCss(ss2);

             dependencias.put(bean.getNombre(), bean);
        }
      }
      catch (JSONException e)
      {
           e.printStackTrace();
      }
    }
  }

  private static String generarScript(Set dependenciasJS, Set dependenciasCSS)
  {
       String staticFormatLiteral = "";

       String aliasCSS = Q70ListenerUtils.getApplicationResourceURI("ALIAS_ESTATICO", "ALIAS_CSS");
       String aliasJS = Q70ListenerUtils.getApplicationResourceURI("ALIAS_ESTATICO", "ALIAS_JAVASCRIPT");

       if ((Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS") == null) || (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals(""))) {
         EstaticosClsTrazas.error("No se ha especificado la propiedad \"FORMATO_ESTATICOS_SERVIDOS\" en el fichero de properties de la aplicación. Para el correcto funcionamiento de la infraestructura, es necesaria la especificacion de dicha propiedad en el properties de la aplicacion. Para resolver el problema de configuracion se considerara el valor \"stardard\" por defecto", W83aCargadorEstaticos.class);
    }
       else if (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals("min")) {
         staticFormatLiteral = "-min";
         aliasCSS = aliasCSS.substring(0, aliasCSS.length() - 1) + staticFormatLiteral + "/";
         aliasJS = aliasJS.substring(0, aliasJS.length() - 1) + staticFormatLiteral + "/";
    }

       StringBuffer script = new StringBuffer();//NOPMD
       Iterator iterJs = dependenciasJS.iterator();

       RecursoEstaticosBean recursoBean = new RecursoEstaticosBean();

       if (dependenciasJS.size() > 0)
    {
         while (iterJs.hasNext()) {
           recursoBean = (RecursoEstaticosBean)iterJs.next();
           if ((recursoBean.getType() != null) && (recursoBean.getType().equals("url"))) {
             String url = recursoBean.getName();
             if (url.split("=").length > 1) {
               script.append("<script src=\"/" + war + "/" + url + "&" + System.currentTimeMillis() + "\"></script>");
          }
          else
               script.append("<script src=\"/" + war + "/" + url + "?" + System.currentTimeMillis() + "\"></script>");
        }
        else
        {
             String url = recursoBean.getName();
             script.append("<script src=\"" + aliasJS + url.substring(0, url.length() - 3) + staticFormatLiteral + ".js" + "\" type=\"text/javascript\"></script>");
        }
      }
    }

       if (dependenciasCSS.size() > 0)
    {
         Iterator iterCss = dependenciasCSS.iterator();
         while (iterCss.hasNext()) {
           recursoBean = (RecursoEstaticosBean)iterCss.next();
           String url = recursoBean.getName();
           script.append("<link href=\"" + aliasCSS + url.substring(0, url.length() - 4) + staticFormatLiteral + ".css" + "\" rel=\"stylesheet\" type=\"text/css\" />");
      }
    }

       return script.toString();
  }
  
  private static String generarScriptJS(Set dependenciasJS)
  {
	  String staticFormatLiteral = "";
	  
	  String aliasJS = Q70ListenerUtils.getApplicationResourceURI("ALIAS_ESTATICO", "ALIAS_JAVASCRIPT");
	  
	  if ((Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS") == null) || (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals(""))) {
		  EstaticosClsTrazas.error("No se ha especificado la propiedad \"FORMATO_ESTATICOS_SERVIDOS\" en el fichero de properties de la aplicación. Para el correcto funcionamiento de la infraestructura, es necesaria la especificacion de dicha propiedad en el properties de la aplicacion. Para resolver el problema de configuracion se considerara el valor \"stardard\" por defecto", W83aCargadorEstaticos.class);
	  }
	  else if (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals("min")) {
		  staticFormatLiteral = "-min";
		  aliasJS = aliasJS.substring(0, aliasJS.length() - 1) + staticFormatLiteral + "/";
	  }
	  
	  StringBuffer script = new StringBuffer();//NOPMD
	  Iterator iterJs = dependenciasJS.iterator();
	  
	  RecursoEstaticosBean recursoBean = new RecursoEstaticosBean();
	  
	  if (dependenciasJS.size() > 0)
	  {
		  while (iterJs.hasNext()) {
			  recursoBean = (RecursoEstaticosBean)iterJs.next();
			  if ((recursoBean.getType() != null) && (recursoBean.getType().equals("url"))) {
				  String url = recursoBean.getName();
				  if (url.split("=").length > 1) {
					  script.append("<script src=\"/" + war + "/" + url + "&" + System.currentTimeMillis() + "\"></script>");
				  }
				  else
					  script.append("<script src=\"/" + war + "/" + url + "?" + System.currentTimeMillis() + "\"></script>");
			  }
			  else
			  {
				  String url = recursoBean.getName();
				  script.append("<script src=\"" + aliasJS + url.substring(0, url.length() - 3) + staticFormatLiteral + ".js" + "\" type=\"text/javascript\"></script>");
			  }
		  }
	  }
	  
	  return script.toString();
  }
  
  private static String generarScriptCSS(Set dependenciasCSS)
  {
	  String staticFormatLiteral = "";
	  
	  String aliasCSS = Q70ListenerUtils.getApplicationResourceURI("ALIAS_ESTATICO", "ALIAS_CSS");
	  
	  if ((Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS") == null) || (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals(""))) {
		  EstaticosClsTrazas.error("No se ha especificado la propiedad \"FORMATO_ESTATICOS_SERVIDOS\" en el fichero de properties de la aplicación. Para el correcto funcionamiento de la infraestructura, es necesaria la especificacion de dicha propiedad en el properties de la aplicacion. Para resolver el problema de configuracion se considerara el valor \"stardard\" por defecto", W83aCargadorEstaticos.class);
	  }
	  else if (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals("min")) {
		  staticFormatLiteral = "-min";
		  aliasCSS = aliasCSS.substring(0, aliasCSS.length() - 1) + staticFormatLiteral + "/";
	  }
	  
	  StringBuffer script = new StringBuffer();//NOPMD
	  
	  RecursoEstaticosBean recursoBean = new RecursoEstaticosBean();
	  
	  if (dependenciasCSS.size() > 0)
	  {
		  Iterator iterCss = dependenciasCSS.iterator();
		  while (iterCss.hasNext()) {
			  recursoBean = (RecursoEstaticosBean)iterCss.next();
			  String url = recursoBean.getName();
			  script.append("<link href=\"" + aliasCSS + url.substring(0, url.length() - 4) + staticFormatLiteral + ".css" + "\" rel=\"stylesheet\" type=\"text/css\" />");
		  }
	  }
	  
	  return script.toString();
  }

  private static String generarScriptUrlJS(Set dependenciasJS, String cadena)
  {
       String staticFormatLiteral = "";

       String aliasJS = Q70ListenerUtils.getApplicationResourceURI("ALIAS_ESTATICO", "ALIAS_JAVASCRIPT");

       if ((Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS") == null) || (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals(""))) {
         EstaticosClsTrazas.error("No se ha especificado la propiedad \"FORMATO_ESTATICOS_SERVIDOS\" en el fichero de properties de la aplicación. Para el correcto funcionamiento de la infraestructura, es necesaria la especificacion de dicha propiedad en el properties de la aplicacion. Para resolver el problema de configuracion se considerara el valor \"stardard\" por defecto", W83aCargadorEstaticos.class);
    }
       else if (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals("min")) {
         staticFormatLiteral = "-min";
         aliasJS = aliasJS.substring(0, aliasJS.length() - 1) + staticFormatLiteral + "/";
    }

       StringBuffer script = new StringBuffer();//NOPMD

      Iterator iterJs = dependenciasJS.iterator();
       RecursoEstaticosBean recursoBean = null;

       String url = null;

       if (dependenciasJS.size() > 0) {
         while (iterJs.hasNext()) {
           recursoBean = (RecursoEstaticosBean)iterJs.next();
           if ((recursoBean.getType() != null) && (recursoBean.getType().equals("url"))) {
             url = recursoBean.getName();
             if (url.split("=").length > 1) {
               script.append("<script src=\"/" + war + "/" + url + "&" + System.currentTimeMillis() + "\"></script>");
          }
          else {
               script.append("<script src=\"/" + war + "/" + url + "?" + System.currentTimeMillis() + "\"></script>");
          }

        }
           else if ((recursoBean.getType() != null) && (recursoBean.getType().equals("absoluta"))) {
             url = recursoBean.getName();
             script.append("<script src=\"" + cadena + "/" + url + "\"></script>");
        }
        else {
             url = recursoBean.getName();
             script.append("<script src=\"" + aliasJS + url.substring(0, url.length() - 3) + staticFormatLiteral + ".js" + "\" type=\"text/javascript\"></script>");
        }
      }
    }

       return script.toString();
  }
  
  private static String generarScriptUrlCSS( Set dependenciasCSS, String cadena)
  {
	  String staticFormatLiteral = "";
	  
	  String aliasCSS = Q70ListenerUtils.getApplicationResourceURI("ALIAS_ESTATICO", "ALIAS_CSS");
	  
	  if ((Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS") == null) || (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals(""))) {
		  EstaticosClsTrazas.error("No se ha especificado la propiedad \"FORMATO_ESTATICOS_SERVIDOS\" en el fichero de properties de la aplicación. Para el correcto funcionamiento de la infraestructura, es necesaria la especificacion de dicha propiedad en el properties de la aplicacion. Para resolver el problema de configuracion se considerara el valor \"stardard\" por defecto", W83aCargadorEstaticos.class);
	  }
	  else if (Q70ListenerUtils.getApplicationProperty("FORMATO_ESTATICOS_SERVIDOS").equals("min")) {
		  staticFormatLiteral = "-min";
		  aliasCSS = aliasCSS.substring(0, aliasCSS.length() - 1) + staticFormatLiteral + "/";
	  }
	  
	  StringBuffer script = new StringBuffer();//NOPMD
	  
	  RecursoEstaticosBean recursoBean = null;
	  
	  String url = null;
	  
	  if (dependenciasCSS.size() > 0)
	  {
		  Iterator iterCss = dependenciasCSS.iterator();
		  
		  while (iterCss.hasNext()) {
			  recursoBean = (RecursoEstaticosBean)iterCss.next();
			  url = recursoBean.getName();
			  if ((recursoBean.getType() != null) && (recursoBean.getType().equals("absoluta"))) {
				  script.append("<link href=\"" + cadena + "/" + url + "\" rel=\"stylesheet\" type=\"text/css\" />");
			  }
			  else {
				  script.append("<link href=\"" + aliasCSS + url.substring(0, url.length() - 4) + staticFormatLiteral + ".css" + "\" rel=\"stylesheet\" type=\"text/css\" />");
			  }
		  }
	  }
	  return script.toString();
  }

  public static void definirWar(String urlWar) {
       war = urlWar;
  }
}